﻿using System.Collections.Generic;
using System.Linq;
using BlockLogic.Interface;
using Wintellect.PowerCollections;
using System;
using ActionLogic.Impl;

namespace BlockLogic.Impl
{
    public class RequestBuffer : IRequestBuffer
    {
        private OrderedMultiDictionary<double, IRequest> _buffer;

        public RequestBufferState State { get; private set; }
        public long MaxCapacity { get; set; }

        public Guid ID { get; private set; }
        public event ExecuteFunc OnRequestAdded;

        public RequestBuffer(Guid blockID)
        {
            ID = blockID;
            _buffer = new OrderedMultiDictionary<double, IRequest>(true);
            State = RequestBufferState.EMPTY;
            MaxCapacity = 0;
        }

        public RequestBuffer(Guid blockID, long maxCapacity)
        {
            ID = blockID;
            _buffer = new OrderedMultiDictionary<double, IRequest>(true);
            State = RequestBufferState.EMPTY;
            MaxCapacity = maxCapacity;
        }


        public void Add(IRequest request)
        {
            if (State != RequestBufferState.FULL)
            {
                if (0 == MaxCapacity || _buffer.Count < MaxCapacity)
                {
                    _buffer.Add(request.InitTime, request);
                    State = RequestBufferState.NOT_EMPTY;

                    if (OnRequestAdded != null)
                    {
                        OnRequestAdded();
                    }
                }
                else
                {
                    State = RequestBufferState.FULL;
                }
            }
        }

        public IEnumerable<IRequest> Get()
        {
            ICollection<IRequest> collect = new List<IRequest>();
            
            if (!IsEmtpy())
            {
                var minKey = _buffer.Keys.Min();
                var requests = _buffer[minKey];

                foreach (var r in requests)
                {
                    collect.Add(r);
                }
                _buffer.Remove(minKey);
            }

            return collect;
        }

        public IEnumerable<IRequest> GetAllRequest()
        {
            var requests = new List<IRequest>();
            
            foreach (var request in _buffer)
            {
                requests.AddRange(request.Value);
            }
            //_buffer.Clear();

            return requests;
        }

        public bool IsEmtpy()
        {
            return _buffer.Count == 0;
        }

        public void Clear()
        {
            _buffer.Clear();
            State = RequestBufferState.EMPTY;
        }

        public int Count()
        {
            return _buffer.Count;
        }

        public double GetLastRequestTime()
        {
            var maxKey = _buffer.Keys.Max();
            var requests = _buffer[maxKey];

            return requests.ElementAt(0).InitTime;
        }
    }
}
